package com.dayu.finecomm.dsc.net;

import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.dayu.finecomm.dsc.DSCInterface;

/**
 * 对Socket的管理，包括创建、读取、发送等操作
 * 
 * @author hddz
 * @since 2017-07-26 12:01:00
 * @version V1.0
 */
public class DSCNetManager {
	static Logger LOGGER = LoggerFactory.getLogger(DSCNetManager.class);

	/**
	 * 创建的Socket类型
	 */
	public static final int DSC_NET_NONE = 0; // None
	public static final int DSC_NET_TCP = 1; // TCP Socket
	public static final int DSC_NET_UDP = 2; // UDP Socket

	/**
	 * 单例模式
	 */
	private volatile static DSCNetManager mSelf = null;

	/**
	 * 保存ChannelFuture
	 */
	List<ChannelFuture> mFutures;

	/**
	 * 保存DSCSocketServer
	 */
	List<DSCSocketServer> mSockets;

	/**
	 * 创建DSCNetManager单例
	 * 
	 * @return DSCNetManager
	 */
	public static DSCNetManager getInstance() {
		if (null == mSelf) {
			synchronized (DSCNetManager.class) {
				if (null == mSelf) {
					mSelf = new DSCNetManager();
				}
			}
		}

		return mSelf;
	}

	private DSCNetManager() {
	}

	/**
	 * 初始化DSCNetManager
	 * 
	 * @throws Exception
	 */
	public void init() {
		mFutures = new ArrayList<>();
		mSockets = new ArrayList<>();
	}

	/**
	 * 销毁所有监听socket
	 */
	public void uninit() {
		for (DSCSocketServer socket : mSockets) {
			socket.shutdown();
		}

		mFutures.clear();
		mSockets.clear();
	}

	/**
	 * 创建监听Socket，TCP or UDP
	 * 
	 * @param nType
	 *            DSC_NET_TCP, DSC_NET_UDP
	 * @param nPort
	 *            本地端口号
	 * @param list
	 *            List<ChannelHandler>
	 * @return 0 - success, -1 - failed
	 */
	public int createSocket(int nType, int nPort, DSCInterface callback) {
		return createSocket(nType, null, nPort, callback);
	}

	/**
	 * 创建监听Socket，TCP or UDP
	 * 
	 * @param nType
	 *            DSC_NET_TCP, DSC_NET_UDP
	 * @param strHost
	 *            hostname
	 * @param nPort
	 *            本地端口号
	 * @param list
	 *            List<ChannelHandler>
	 * @return 0 - success, -1 - failed
	 */
	public int createSocket(int nType, String strHost, int nPort,
			DSCInterface callback) {
		int nResult = -1;
		DSCSocketServer socket = null;

		if (DSC_NET_TCP == nType) {
			socket = new DSCTcpServer(strHost, nPort, callback);
		} else if (DSC_NET_UDP == nType) {
			socket = new DSCUdpServer(strHost, nPort, callback);
		} else {
			// none
		}

		if (null != socket) {
			try {
				ChannelFuture cf = socket.bootstrap();
				if (null != cf) {
					mFutures.add(cf);
					mSockets.add(socket);
					nResult = 0;
				}
			} catch (InterruptedException e) {
				if (null == strHost) {
					LOGGER.error("Create Socket(" + nType + ") :" + nPort
							+ " failed", e);
				} else {
					LOGGER.error("Create Socket(" + nType + ") " + strHost
							+ ":" + nPort + " failed", e);
				}
			}
		}

		return nResult;
	}

	/**
	 * 发送数据
	 * 
	 * @param channel
	 *            发送通道
	 * @param msg
	 *            发送内容
	 */
	public void Send(Channel channel, Object msg) {
		try {
			DSCSocketServer.Send(channel, msg);
		} catch (Exception e) {
			LOGGER.error("Send message failed ", e);
		}
	}
}
